
/* GCSx
** COLORSELECT.H
**
** Color selection toolbar
*/

/*****************************************************************************
** Copyright (C) 2003-2006 Janson
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
*****************************************************************************/

#ifndef __GCSx_COLORSELECT_H_
#define __GCSx_COLORSELECT_H_

struct ColorStore {
    struct {
        Uint8 r;
        Uint8 g;
        Uint8 b;
        Uint8 a;
    } fg;
    struct {
        Uint8 r;
        Uint8 g;
        Uint8 b;
        Uint8 a;
    } bk;
};

class ColorSelect : public Window {
private:
    class FrameWindow* myFrame;
    ColorStore* storage;

    enum {
        // Number of colors to make available
        NUM_COLORS = 11,
        // Size of color tiles (width)
        COLOR_SIZE = 14,
        // Separation between color tiles
        COLOR_SEPARATION = 1,

        // Bevel size on tiles
        COLOR_BEVEL = 1,
        // Tile height
        COLOR_HEIGHT = 20,
    };

    // Colors (R G B A)
    Uint8 color[NUM_COLORS][4];

    // Do we support fg or fg+bk?
    int numColors;
    int bitDepthAlpha;
    int bitDepth;
    int maxComponent;
    int maxAlpha;

    // Selected
    int selected[2];
    int selectedFirst[2]; // (can select a range)
    int selectedLast[2];

    // Default colors (R G B A)
    static Uint8 defaultColors[NUM_COLORS][4];
    static int defaultSelected[2];

    // Fg/Bk markers
    static const std::string wtArrowUp;
    static const std::string wtArrowDown;

    static int arrowHeight;
    static int arrowXOffset;
    
    // Save state to storage
    void apply();

public:
    enum {
        // Selected types
        SELECTED_FG = 0,
        SELECTED_BK = 1,
    };
    
    ColorSelect(ColorStore* cStorage, int defaultTransparent, int allowBk = 1, int alphaBitDepth = 8, int myBitDepth = 8);

    // Creates a FrameWindow and returns, does not add self to desktop (use ->show() to do that)
    class FrameWindow* createWindowed();

    int event(int hasFocus, const SDL_Event* event);
    void display(SDL_Surface* destSurface, Rect& toDisplay, const Rect& clipArea, int xOffset, int yOffset);
    Window::CommandSupport supportsCommand(int code) const;
    const char* tooltip(int xPos, int yPos) const;

    // Returns a position
    int colorSelection(int which) const;
    int colorSelection(int which, int newPos, int drag = 0);

    // Edits a color at a given position
    void editColor(int pos);

    // Adds a color, to the next logical position to put it at, or to
    // current position if 'putInCurrent' true
    // Moves selection to point to it and returns position it was added at
    int addColor(int which, Uint8 r, Uint8 g, Uint8 b, Uint8 a, int putInCurrent);

    // Changes settings
    void alphaDepth(int newAlphaDepth);
    void changeDefaultTransparent(int defaultTransparent);
};

inline int scaleComponent(int from, int fromMax, int toMax) { assert(fromMax); return (from * toMax + (fromMax / 2)) / fromMax; }

#endif

